/*
 *  Arrow
 *
 *  Created by David Giovannini on 1/5/07.
 *  Copyright 2007 Software by Jove. All rights reserved.
 *
 */
 
namespace SBJ
{

namespace Arrow
{

template < typename MsgType > Publication*
PublicationMgr::findPublication( void ) const
{
	return findPublication( typeid( MsgType ).name() );
}

template < typename MsgType > Publication&
PublicationMgr::publish( const std::string& pubKey )
{
	Publication& pub( addPublication< MsgType >( pubKey ) );
	pub.publish< MsgType >();
	return pub;
}

template < typename MsgType, typename Allocator > Publication&
PublicationMgr::publishWithAlloc( const Allocator& allocator, const std::string& pubKey )
{
	Publication& pub( addPublication< MsgType >( pubKey ) );
	pub.publishWithAlloc< MsgType, Allocator >( allocator );
	return pub;
}

template < typename MsgType > Publication&
PublicationMgr::addPublication( const std::string& pubKey )
{
	Publication* pub = 0;
	const char* typeName = typeid( MsgType ).name();
	std::string localPubKey;
	if ( pubKey.empty() )
	{
		localPubKey = typeName;
	}
	else
	{
		localPubKey = pubKey;
	}
	{
		boost::mutex::scoped_lock lock( m_publicationGuard );

		std::pair< KeyedPublications::iterator, bool > insertPubKey = m_publications.insert(
			std::make_pair( localPubKey, static_cast< Publication* >( 0 ) ) );
		
		if ( insertPubKey.second == true )
		{
			insertPubKey.first->second = new Publication( localPubKey, m_excObserver );
		}
		pub = insertPubKey.first->second;
	}
	return *pub;
}

template < typename MsgType > Topic
PublicationMgr::makeTopic( const std::string& topicKey )
{
	Publication* pub = findPublication< MsgType >();
	if ( pub != 0 )
	{
		return pub->makeTopic< MsgType >( topicKey );
	}
	return Topic();	
}

template < typename MsgType > Topic
PublicationMgr::getTopic( const std::string& topicKey ) const
{
	Publication* pub = findPublication< MsgType >();
	if ( pub != 0 )
	{
		return pub->getTopic< MsgType >( topicKey );
	}
	return Topic();	
}

}

}
